/**
 * 
 */
package com.csair.youth.service.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;

import com.csair.youth.constant.Constant;
import com.csair.youth.dao.impl.hibernate3.CategoryDaoImpl;
import com.csair.youth.database.Category;
import com.csair.youth.domain.TreeNode;

/**
 * @author mickey
 *
 */
public class CategoryServiceImpl {
	private CategoryDaoImpl cdao;

	public CategoryDaoImpl getCdao() {
		return cdao;
	}

	public void setCdao(CategoryDaoImpl cdao) {
		this.cdao = cdao;
	}

	public void saveCategory(Category item){
		if(item == null) return;
		if(StringUtils.isEmpty(item.getId())) item.setId(null);
		//生成路径
//		String pathPrefix = getCategoryAbsolutePath(item.getParentId());
//		item.setPath(pathPrefix + File.separator + item.getName());
		cdao.saveOrUpdate(item);
	}
	
	public void deleteCategoryById(String id){
		if(!StringUtils.isEmpty(id)) cdao.deleteById(id);
	}
	
	public void deleteCategoryAndSub(String id){
		if(!StringUtils.isEmpty(id)){
			Map<String, TreeNode> nodes = buildCategoryTree(null, false);
			TreeNode n = nodes.get(id);
			LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
			if(n == null) return;
			queue.add(n);
			List<String> deleteIds = new ArrayList<String>();
			TreeNode xx = null;
			while((xx = queue.poll()) != null){
				queue.addAll(xx.getChildren());
				deleteIds.add(xx.getId());
			}
			cdao.deleteCategoryAndSub(deleteIds);
		}
	}
	
	public Category getCategory(String id){
		if(id == null) return null;
		return cdao.findById(id);
	}
	
	/**
	 * 构建树，返回root
	 * @return
	 */
	public Map<String, TreeNode> buildCategoryTree(String selfId, boolean escapeSelf){
		Map<String, TreeNode> nodes = new HashMap<String, TreeNode>();
		//没有找到父节点的node集合，暂时记录
		Map<String, TreeNode> nodesNotYetFoundParent = new HashMap<String, TreeNode>();
		List categories = cdao.findAllList();
		if(categories == null || categories.size() == 0){
			return null;
		}
		else{
			Iterator iter = categories.iterator();
			while(iter.hasNext()){
				Category c = (Category)iter.next();
				if(escapeSelf && c.getId().equals(selfId)) continue;
				TreeNode node = new TreeNode();
				node.setId(c.getId());
				node.setName(c.getName());
				node.setDescription(c.getDescription());
				node.setChildren(new ArrayList<TreeNode>());
				nodes.put(node.getId(), node);
				if(StringUtils.isEmpty(c.getParentId())){
					//the root...
					nodes.put("ROOT", node);
				}
				else{
					//not the root...
					TreeNode parent = nodes.get(c.getParentId());
					node.setParentId(c.getParentId());
					if(null == parent){
						//its parent did not add to nodes yet
						nodesNotYetFoundParent.put(node.getId(), node);
					}
					else{
						node.setParent(parent);
						parent.getChildren().add(node);
					}
				}
			}
			Set<String> keys = nodesNotYetFoundParent.keySet();
			Iterator<String> iter2 = keys.iterator();
			while(iter2.hasNext()){
				String key = iter2.next();
				TreeNode node = nodesNotYetFoundParent.get(key);
				TreeNode parent = nodes.get(node.getParentId());
				node.setParent(parent);	//if null, 不鸟之
				if(parent != null) parent.getChildren().add(node);
			}
			return nodes;
		}
	}
	
	public String buildCategoryTreeString(TreeNode root, String treeId, String scriptFunction){
		if(root == null) return "";
		StringBuffer sb = new StringBuffer();
		sb.append("<ul id='"+treeId+"'>");
		sb.append("<li><a href='#' onclick='"+scriptFunction+"' title='"+root.getDescription()+"' tvalue='"+root.getId()+"'>"+root.getName()+"</a>");
		sb.append(buildNodeChildren(root.getChildren(), scriptFunction));
		sb.append("</li></ul>");
		return sb.toString();
	}
	
	private String buildNodeChildren(List<TreeNode> children, String scriptFunction){
		if(children == null || children.size() == 0){
			return "";
		}
		StringBuffer sb = new StringBuffer();
		sb.append("<ul>");
		Iterator<TreeNode> iter = children.iterator();
		while(iter.hasNext()){
			TreeNode node = iter.next();
			sb.append("<li><a href='#' onclick='"+scriptFunction+"' title='"+node.getDescription()+"' tvalue='"+node.getId()+"'>"+node.getName()+"</a>");
			sb.append(buildNodeChildren(node.getChildren(), scriptFunction));
			sb.append("</li>");
		}
		sb.append("</ul>");
		return sb.toString();
	}
	
	public boolean isParentSelectedSelfOrChild(String target, String self){
		TreeNode root = buildCategoryTree(null, false).get("ROOT");
		if(root == null) return false;
		LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
		queue.add(root);
		TreeNode xx = null;
		TreeNode yy = null;
		while((xx = queue.poll()) != null){
			if(xx.getId().equals(target)){
				yy = xx;
				break;
			}
			queue.addAll(xx.getChildren());
		}
		if(yy != null){
			while(yy != null && !yy.getId().equals(self)){
				yy = yy.getParent();
			}
			if(yy != null){
				//匹配了。。。
				return true;
			}
			else return false;
		}
		else{
			return false;
		}
	}
	
	/**
	 * 
	 * @param id
	 * @param sep if null, use File.separator, otherwise use sep
	 * @return
	 */
	public String getCategoryAbsolutePath(String id, String sep){
		if(sep == null)sep = File.separator;
		Category cc = getCategory(id);
		String path = "";
		while(cc != null && cc.getParentId() != null){
			path = sep + replaceBanChars(cc.getName()) + path;
			cc = getCategory(cc.getParentId());
		}
		return path;
	}
	
	public void initGlobalCategories(){
		Category root = cdao.getRootCategory();
		if(null == root){
			root = new Category();
			root.setDescription("ROOT");
			root.setName("ROOT");
			root.setParentId(null);
			cdao.save(root);
		}
		if(null == cdao.getCategoryByName(Constant.CATEGORY_FTP_AUTO_NAME)){
			Category ftpAuto = new Category();
			ftpAuto.setDescription("ftp自动上传，未分类，请勿删除本分类，且不要修改本分类的名字!!!");
			ftpAuto.setName(Constant.CATEGORY_FTP_AUTO_NAME);
			ftpAuto.setParentId(root.getId());
			cdao.save(ftpAuto);
		}
	}
	
	/**
	 * 替换掉不允许在文件名和文件路径出现的字符
	 * \/:*?"<>|
	 * @param name
	 * @return
	 */
	public String replaceBanChars(String name){
		String pattern = "[\\\\/:\\*\\?\"<>\\|]";
		return name.replaceAll(pattern, "_");
	}
	
	/**
	 * 由分类树构建所有分类的物理路径
	 * @param root
	 * @return
	 */
	public Map<TreeNode, String> getCategoryPathsUnique(TreeNode root){
		if(root == null) return null;
//		List<String> ret = new ArrayList<String>();
		Map<TreeNode, String> nodeAndPath = new HashMap<TreeNode, String>();
		nodeAndPath.put(root, "");
		LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
		queue.add(root);
		TreeNode xx = null;
		while((xx = queue.poll()) != null){
			if(xx != root){
				String parentPath = "";
				if(xx.getParentId() != null){
					parentPath = nodeAndPath.get(xx.getParent());
				}
				String currentPath = parentPath + File.separator + xx.getName();
				nodeAndPath.put(xx, currentPath);
//				ret.add(currentPath);
			}
			queue.addAll(xx.getChildren());
		}
		return nodeAndPath;
	}
}
